package com.idss.common.mvc.view;

import cloud.agileframework.common.constant.Constant;
import cloud.agileframework.mvc.base.AbstractResponseFormat;
import cloud.agileframework.mvc.base.Head;
import cloud.agileframework.mybatis.page.Page;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 佟盟 on 2018/10/29
 */
@Component
public class ResponseData extends AbstractResponseFormat {
    private static final String STATUS = "status";
    private static final String ERROR_CODE = "errorCode";
    private static final String MESSAGE = "message";
    private static final String CONTENT = "content";
    private static final String TOTAL = "total";
    private static final String DATA = "data";

    /**
     * 状态
     */
    public enum StatusType {
        /**
         * 成功
         */
        success,
        /**
         * 失败
         */
        error,
        exception,
        warn,
        info,
        unknown
    }

    @Override
    public Map<String, Object> buildResponseData(Head head, Object result) {
        Map<String, Object> map = new HashMap<>(Constant.NumberAbout.TWO);

        String firstCode = head.getCode().substring(Constant.NumberAbout.ZERO, Constant.NumberAbout.ONE);
        switch (firstCode) {
            case "0":
                map.put(STATUS, StatusType.success);
                break;
            case "1":
                map.put(STATUS, StatusType.error);
                break;
            case "2":
                map.put(STATUS, StatusType.exception);
                break;
            case "3":
                map.put(STATUS, StatusType.warn);
                break;
            case "4":
                map.put(STATUS, StatusType.info);
                break;
            default:
                map.put(STATUS, StatusType.unknown);
                break;
        }

        map.put(ERROR_CODE, head.getCode());
        map.put(MESSAGE, head.getMsg());
        if (result instanceof org.springframework.data.domain.Page) {
            map.put(CONTENT, new HashMap<String, Object>(Constant.NumberAbout.TWO) {{
                put(TOTAL, ((org.springframework.data.domain.Page<?>) result).getTotalElements());
                put(DATA, ((org.springframework.data.domain.Page<?>) result).getContent());
            }});
        } else if (result instanceof Page) {
            map.put(CONTENT, new HashMap<String, Object>(Constant.NumberAbout.TWO) {{
                put(TOTAL, ((Page<?>) result).getTotal());
                put(DATA, ((Page<?>) result).getContent());
            }});
        } else if (result != null && Map.class.isAssignableFrom(result.getClass())
                && ((Map<?, ?>) result).containsKey("pageable")
                && ((Map<?, ?>) result).containsKey("total")
                && ((Map<?, ?>) result).containsKey("content")) {
            map.put(CONTENT, new HashMap<String, Object>(Constant.NumberAbout.TWO) {{
                put(TOTAL, ((Map<?, ?>) result).get("total"));
                put(DATA, ((Map<?, ?>) result).get("content"));
                ((Map<?, ?>) result).remove("total");
                ((Map<?, ?>) result).remove("content");
                putAll((Map) result);
            }});
        } else {
            map.put(CONTENT, result == null ? Maps.newHashMap() : result);
        }
        return map;
    }
}